const fs = require("fs");
const path = require("path");

(async () => {
  return;
  const filename = path.resolve(__dirname, "index.js");
  const newFilename = path.resolve(__dirname, "index3.js");
  console.log(filename);

  // 读取文件
  const content = await fs.promises.readFile(filename);
  // 写入文件
  const write = await fs.promises.writeFile(newFilename, content);
  console.log(content);
  console.log(write);
  process.exit();
})();

// 简单小demo 文件相关
(function () {
  return;
  // const fs = require("fs");
  // const path = require("path");
  (async () => {
    return;
    const filename = path.resolve(__dirname);
    const readdir = await fs.promises.readdir(filename);
    console.log(readdir);
  })();
  (function () {
    // return

    class File {
      constructor(filename, name, ext, isFile, size, createTime, updateTime) {
        this.filename = filename;
        this.name = name;
        this.ext = ext;
        this.isFile = isFile;
        this.size = size;
        this.createTime = createTime;
        this.updateTime = updateTime;
      }
      async getContent(isBuffer = false) {
        if (this.isFile) {
          if (isBuffer) {
            return await fs.promises.readFile(this.filename);
          } else {
            return await fs.promises.readFile(this.filename, "utf-8");
          }
        }
        return null;
      }
      async getChildren(isBuffer = false) {
        if (this.isFile) {
          return [];
        } else {
          // console.log("进来了,是文件夹");
          let childrens = await fs.promises.readdir(this.filename);
          childrens = childrens.map((basename) => {
            return File.getFile(path.resolve(this.filename, basename));
          });
          // console.log("这里是promise对象", childrens);
          return Promise.all(childrens);
        }
      }
      static async getFile(filename) {
        const stat = await fs.promises.stat(filename);
        const name = path.basename(filename);
        const ext = path.extname(filename);
        const isFile = stat.isFile();
        const size = stat.size;
        const createTime = new Date(stat.birthtime);
        const updateTime = new Date(stat.mtime);
        // console.log(stat)
        return new File(
          filename,
          name,
          ext,
          isFile,
          size,
          createTime,
          updateTime
        );
      }
    }
    async function test1(filename) {
      const dirname = path.resolve(__dirname, filename);
      const file = await File.getFile(dirname);

      return file;
      // console.log(dirname);
      // console.log(file);
    }

    async function fileGetContent(basename) {
      const file = await test1(basename);
      let content = await file.getChildren();
      content = content.map((file) => {
        if (file.isFile) {
          return file.name;
        } else {
          const currentPath = path.resolve(basename, file.name);
          return fileGetContent(currentPath);
        }
      });
      content = await Promise.all(content);

      const self = {
        self: file.name,
        content,
      };

      return self;

      // console.log(content);
    }
    fileGetContent("./getFiles").then((res) => {
      fs.promises.writeFile(
        path.resolve(__dirname, "index3.js"),
        JSON.stringify(res),
        "utf-8"
      );
    });
  })();
})();

// 文件流相关
// 读
(function () {
  // return
  // highWaterMark:  utf-8 1就是一个字符(3个字符),  默认为null.1为一个字节
  const rs = fs.createReadStream(path.resolve(__dirname, "./txt.txt"), {
    encoding: "utf-8", //默认为null,buffer
    highWaterMark: 100,
    autoClose: true, // 默认是自动关闭,
  });
  //
  rs.on("open", () => {
    console.log("文件被打开了"); // 并没有获取
  });
  let num = 0;
  // 必须要注册这个事件,才开始读取文件
  rs.on("data", (chunk) => {
    console.log("读到了一部分", chunk);
    num++;
    if (num === 2) {
      rs.pause();
      console.log("123465");
      setTimeout(() => {
        rs.resume();
      }, 1000);
    }
  });
  // // 出错是出发
  // rs.on("error", () => {
  //     console.log("文件出错了");
  //   });

  // // 关闭时触发 , 读完了会触发, 主动关闭也会触发
  rs.on("close", () => {
    console.log("文件关闭了");
  });

  rs.on("end", () => {
    console.log("文件end");
  });

  // rs.pause(); // 暂停读取 // 触发对应的pause事件
  // rs.resume(); // 恢复读取 // 触发对应的resume事件

  rs.on("pause", () => {
    console.log("暂停了");
  });
  rs.on("resume", () => {
    console.log("恢复了1");
  });
})();

// 文件流相关, 写
(function () {
  return;
  const fs = require("fs");
  const path = require("path");

  const filename = path.resolve(__dirname, "./txt2.txt");
  const ws = fs.createWriteStream(filename, {
    encoding: "utf-8",
    highWaterMark: 3, //每次写入的字节数
  });

  // ws.open() // 打开事件
  // ws.error() // 错误事件
  // ws.close() // 关闭事件

  // const flag = ws.write("a");;
  // flag 为true时, 可以理解为通道通畅,可以继续直接写入 (举例通道3字节, 先写了2个,还有1个字节位置)
  // flag 为false , 无通道, 进入写入队列 (内存里面的队列)
  console.log(ws.write("a")); // true
  console.log(ws.write("a")); // true
  console.log(ws.write("a")); // false
  console.log(ws.write("a")); // false
  console.log(ws.write("a")); // false
  console.log(ws.write("a")); // false

  // 写10兆的文件  这段代码写入10M文件, 代码执行只要4秒钟, 真正的磁盘写入花了40秒
  // console.time("beiya");
  // for (let i = 0; i < 1024 * 1024 * 10; i++) {
  //   ws.write(String(Math.random()).slice(2, 3));
  // }
  // console.timeEnd("beiya");

  // 内存备压问题
  // 利用 flag=ws.write("a")
  // 其中flag来解决
  let i = 0;
  // 一直写, 直到到达上限,或无法再直接写入
  function write() {
    let flag = true;
    while (i < 1024 * 1024 * 10 && flag) {
      flag = ws.write(String(Math.random()).slice(2, 3));
      i++;
    }
  }
  write();
  ws.on("drain", () => {
    console.log("可以再次写入");
    write();
  });
})();

// 文件流的复制方法
(function () {
  // return
  const fs = require("fs");
  const path = require("path");

  // 文件的复制,
  // 第一种方法:

  async function method1() {
    const from = path.resolve(__dirname, "./copy1.txt");
    const to = path.resolve(__dirname, "./copy2.txt");
    const content = await fs.promises.readFile(from);
    await fs.promises.writeFile(to, content, "utf-8");
    console.log("复制完成");
  }
  console.time("fangshi1");
  method1();
  console.timeEnd("fangshi1");

  // 第二种文件流的方式读取
  async function method2() {
    const from = path.resolve(__dirname, "./copy1.txt");
    const to = path.resolve(__dirname, "./copy2.txt");

    const rs = fs.createReadStream(from);
    const ws = fs.createWriteStream(to);

    rs.on("data", (chunk) => {
      const flag = ws.write(chunk);
      if (!flag) {
        // 表示下一次写入, 会造成背压
        rs.pause();
      }
    });

    ws.on("drain", () => {
      rs.resume();
    });

    rs.on("close", () => {
      ws.end(); // 关闭写入流
      console.log("复制完成222");
    });

    //   console.log("复制完成222");
  }
  console.time("fangshi2");
  method2();
  console.timeEnd("fangshi2");

  //=============
  // 一种简化的方法
  // rs.pipe (ws)
  //=============
})();
